package com.tiantian.web.controller.topic;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.tiantian.common.annotation.Log;
import com.tiantian.common.constant.SystemConfigConstants;
import com.tiantian.common.constant.TopicConstants;
import com.tiantian.common.core.controller.BaseController;
import com.tiantian.common.core.domain.ResponseResult;
import com.tiantian.common.core.domain.dto.AnswerTimeDAO;
import com.tiantian.common.core.domain.model.LoginUser;
import com.tiantian.common.core.page.TableDataInfo;
import com.tiantian.common.enums.BusinessType;
import com.tiantian.common.enums.OperatorType;
import com.tiantian.common.enums.UserType;
import com.tiantian.common.exception.BusinessException;
import com.tiantian.common.utils.DateUtils;
import com.tiantian.common.utils.redis.RedisUtils;
import com.tiantian.topic.domain.entity.SysTopic;
import com.tiantian.topic.domain.vo.SysTopicVO;
import com.tiantian.topic.service.SysReplyService;
import com.tiantian.topic.service.SysTopicService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * (SysTopic)控制层
 *
 * @author tiantian
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/topic")
@Slf4j
public class SysTopicController extends BaseController {

    private final SysTopicService sysTopicService;
    private final SysReplyService sysReplyService;

    /**
     * 查询题目列表
     *
     * @param sysTopic 实体筛选条件
     * @return 分页模型
     */
    @GetMapping("/list")
    public TableDataInfo selectPage(SysTopic sysTopic) {
        // 获取登录用户判断类型
        LoginUser loginUser = getLoginUser();
        Long userId = loginUser.getUserId();
        // 协会内用户直接返回题目数据
        if (loginUser.getUserType().equals(UserType.SYS_USER.getUserType())) {
            // 获取分页参数 进行分页查询
            startPage();
            List<SysTopicVO> topicVOList = sysTopicService.selectTopicVOList(sysTopic);
            for (SysTopicVO sysTopicVO : topicVOList) {
                // 设置完成状态
                int count = sysReplyService.checkReplyUnique(sysTopicVO.getTopicId(), userId);
                sysTopicVO.setIsComplete(count > 0 ? TopicConstants.FINISHED : TopicConstants.UNCOMPLETED);
            }
            return getDataTable(topicVOList);
        } else {
            // 获取系统设置答题的时间
            AnswerTimeDAO ansTime = RedisUtils.get(SystemConfigConstants.SYSTEM_CONFIG_ANSWER_TIME_KEY, AnswerTimeDAO.class);
            if (ObjectUtil.isEmpty(ansTime)) {
                return getDataTable(new ArrayList<>());
            }
            LocalDateTime localDateTimeNow = DateUtils.getCurrentDateTime();

            // 构造开始时间和结束时间
            LocalDateTime startTime = LocalDateTimeUtil.parse(ansTime.getDate() + " " + ansTime.getStart(), "yyyy-MM-dd HH:mm:ss");
            LocalDateTime endTime = LocalDateTimeUtil.parse(ansTime.getDate() + " " + ansTime.getEnd(), "yyyy-MM-dd HH:mm:ss");

            // 判断是否在答题时间范围内
            if (!(localDateTimeNow.isAfter(startTime) && localDateTimeNow.isBefore(endTime))) {
                return getDataTable(new ArrayList<>());
            } else {
                // 获取分页参数 进行分页查询
                startPage();
                List<SysTopicVO> topicVOList = sysTopicService.selectTopicVOList(sysTopic);
                for (SysTopicVO sysTopicVO : topicVOList) {
                    // 设置完成状态
                    int count = sysReplyService.checkReplyUnique(sysTopicVO.getTopicId(), userId);
                    sysTopicVO.setIsComplete(count > 0 ? TopicConstants.FINISHED : TopicConstants.UNCOMPLETED);
                }
                return getDataTable(topicVOList);
            }

        }
    }

    /**
     * 分页查询
     *
     * @param sysTopic 实体筛选条件
     * @return 分页模型
     */
    @GetMapping("/list/author")
    @SaCheckPermission("setTopic")
    public TableDataInfo selectPageByAuthor(SysTopic sysTopic) {
        startPage();
        // 设置作者为当前登录用户
        sysTopic.setAuthorId(getUserId());
        List<SysTopicVO> topicVOList = sysTopicService.selectTopicVOList(sysTopic);
        return getDataTable(topicVOList);
    }


    /**
     * 通过topicId查询题目信息
     *
     * @param topicId 主键
     * @return 单条数据
     */
    @GetMapping("/{topicId}")
    @SaCheckLogin
    public ResponseResult<SysTopic> selectOneById(@PathVariable @NotBlank(message = "题目ID不能为空") String topicId) {
        String userType = getLoginUser().getUserType();
        if (userType.equals(UserType.SYS_USER.getUserType())) {
            return ResponseResult.ok(sysTopicService.selectById(topicId));
        } else {
            // 获取系统设置的时间
            AnswerTimeDAO ansTime = RedisUtils.get(SystemConfigConstants.SYSTEM_CONFIG_ANSWER_TIME_KEY, AnswerTimeDAO.class);
            // 获取当前时间
            LocalDateTime localDateTimeNow = DateUtils.getCurrentDateTime();

            // 构造开始时间和结束时间
            LocalDateTime startTime = LocalDateTimeUtil.parse(ansTime.getDate() + " " + ansTime.getStart(), "yyyy-MM-dd HH:mm:ss");
            LocalDateTime endTime = LocalDateTimeUtil.parse(ansTime.getDate() + " " + ansTime.getEnd(), "yyyy-MM-dd HH:mm:ss");

            // 判断是否在答题时间范围内
            if (!(localDateTimeNow.isAfter(startTime) && localDateTimeNow.isBefore(endTime))) {
                throw new BusinessException("当前时间不在答题时间范围内, 查询题目失败");
            } else {
                return ResponseResult.ok(sysTopicService.selectById(topicId));
            }
        }
    }

    /**
     * 设置题目
     *
     * @param sysTopic 实体类
     * @return 是否添加成功
     */
    @PostMapping("/setting")
    @SaCheckPermission("setTopic")
    @Log(title = "设置题目", businessType = BusinessType.SET_TOPIC, operatorType = OperatorType.ADMIN)
    public ResponseResult<Map<String, Object>> insert(@RequestBody @Valid SysTopic sysTopic) {
        Map<String, Object> ajax = new HashMap<>();
        Long userId = getUserId();
        // 雪花算法生成全局唯一id
        Snowflake snowflake = IdUtil.getSnowflake();
        String topicId = snowflake.nextIdStr();
        sysTopic.setTopicId(topicId);
        // 设置出题人ID和姓名
        sysTopic.setAuthorId(userId);
        // 审核默认通过
        sysTopic.setStatus(TopicConstants.EXAMINE_PASS);
        sysTopic.setAuthorName(getNickName());
        // 填充公共字段
        setCommonFieldInsert(sysTopic);
        Boolean res = sysTopicService.setTopic(sysTopic);
        // 构造响应
        ajax.put("isSetting", res);
        ajax.put("title", sysTopic.getTitle());
        ajax.put("authorName", sysTopic.getAuthorName());
        ajax.put("topicId", sysTopic.getTopicId());
        ajax.put("createTime", sysTopic.getCreateTime());
        return ResponseResult.ok(ajax);
    }


    /**
     * 修改一条数据
     *
     * @param sysTopic 实体类
     * @return 是否修改成功
     */
    @PutMapping("/update")
    @SaCheckPermission("setTopic")
    @Log(title = "修改题目", businessType = BusinessType.UPDATE_TOPIC, operatorType = OperatorType.ADMIN)
    public ResponseResult<Boolean> update(@RequestBody @Valid SysTopic sysTopic) {
        sysTopic.setAuthorId(getUserId());
        setCommonFieldUpdate(sysTopic);
        return ResponseResult.ok(sysTopicService.updateById(sysTopic));
    }

    /**
     * 删除一条数据
     *
     * @param topicId 主键
     * @return Boolean是否删除成功
     */
    @DeleteMapping("/del")
    @SaCheckPermission("setTopic")
    @Log(title = "删除题目", businessType = BusinessType.DEL_TOPIC, operatorType = OperatorType.ADMIN)
    public ResponseResult<Void> delete(String topicId) {
        Boolean res = sysTopicService.deleteById(topicId, getUserId());
        return toAjax(res);
    }

    /**
     * 获取题目总数
     */
    @GetMapping("/total")
    @SaCheckPermission("reply")
    public ResponseResult<Integer> getTopicTotal() {
        return ResponseResult.ok(sysTopicService.getTopicTotal());
    }

}

